package com.hnfnu.contracts;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.fisco.bcos.sdk.v3.client.Client;
import org.fisco.bcos.sdk.v3.codec.datatypes.DynamicArray;
import org.fisco.bcos.sdk.v3.codec.datatypes.DynamicStruct;
import org.fisco.bcos.sdk.v3.codec.datatypes.Event;
import org.fisco.bcos.sdk.v3.codec.datatypes.Function;
import org.fisco.bcos.sdk.v3.codec.datatypes.Type;
import org.fisco.bcos.sdk.v3.codec.datatypes.TypeReference;
import org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String;
import org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.v3.codec.datatypes.generated.tuples.generated.Tuple5;
import org.fisco.bcos.sdk.v3.codec.datatypes.generated.tuples.generated.Tuple6;
import org.fisco.bcos.sdk.v3.contract.Contract;
import org.fisco.bcos.sdk.v3.crypto.CryptoSuite;
import org.fisco.bcos.sdk.v3.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.v3.model.CryptoType;
import org.fisco.bcos.sdk.v3.model.TransactionReceipt;
import org.fisco.bcos.sdk.v3.model.callback.CallCallback;
import org.fisco.bcos.sdk.v3.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.v3.transaction.model.exception.ContractException;

@SuppressWarnings("unchecked")
public class DisburseRecord extends Contract {
    public static final String[] BINARY_ARRAY = {"608060405234801561001057600080fd5b50610ff2806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632d015f811461005157806334461067146100815780634d66ecf9146100b6578063c2a4250b146100d2575b600080fd5b61006b600480360381019061006691906108f9565b6100f0565b6040516100789190610b2e565b60405180910390f35b61009b600480360381019061009691906108f9565b610441565b6040516100ad96959493929190610ba9565b60405180910390f35b6100d060048036038101906100cb9190610d5b565b61069d565b005b6100da6107d0565b6040516100e79190610e46565b60405180910390f35b6060600060015467ffffffffffffffff8111156101105761010f610c30565b5b60405190808252806020026020018201604052801561014957816020015b6101366107d6565b81526020019060019003908161012e5790505b509050600080600190505b60015481116104335784600080838152602001908152602001600020600101541415610420576000808281526020019081526020016000206040518060c001604052908160008201548152602001600182015481526020016002820180546101bb90610e90565b80601f01602080910402602001604051908101604052809291908181526020018280546101e790610e90565b80156102345780601f1061020957610100808354040283529160200191610234565b820191906000526020600020905b81548152906001019060200180831161021757829003601f168201915b5050505050815260200160038201805461024d90610e90565b80601f016020809104026020016040519081016040528092919081815260200182805461027990610e90565b80156102c65780601f1061029b576101008083540402835291602001916102c6565b820191906000526020600020905b8154815290600101906020018083116102a957829003601f168201915b505050505081526020016004820180546102df90610e90565b80601f016020809104026020016040519081016040528092919081815260200182805461030b90610e90565b80156103585780601f1061032d57610100808354040283529160200191610358565b820191906000526020600020905b81548152906001019060200180831161033b57829003601f168201915b5050505050815260200160058201805461037190610e90565b80601f016020809104026020016040519081016040528092919081815260200182805461039d90610e90565b80156103ea5780601f106103bf576101008083540402835291602001916103ea565b820191906000526020600020905b8154815290600101906020018083116103cd57829003601f168201915b50505050508152505083838151811061040657610405610ec2565b5b6020026020010181905250818061041c90610f20565b9250505b808061042b90610f20565b915050610154565b508082528192505050919050565b600060205280600052604060002060009150905080600001549080600101549080600201805461047090610e90565b80601f016020809104026020016040519081016040528092919081815260200182805461049c90610e90565b80156104e95780601f106104be576101008083540402835291602001916104e9565b820191906000526020600020905b8154815290600101906020018083116104cc57829003601f168201915b5050505050908060030180546104fe90610e90565b80601f016020809104026020016040519081016040528092919081815260200182805461052a90610e90565b80156105775780601f1061054c57610100808354040283529160200191610577565b820191906000526020600020905b81548152906001019060200180831161055a57829003601f168201915b50505050509080600401805461058c90610e90565b80601f01602080910402602001604051908101604052809291908181526020018280546105b890610e90565b80156106055780601f106105da57610100808354040283529160200191610605565b820191906000526020600020905b8154815290600101906020018083116105e857829003601f168201915b50505050509080600501805461061a90610e90565b80601f016020809104026020016040519081016040528092919081815260200182805461064690610e90565b80156106935780601f1061066857610100808354040283529160200191610693565b820191906000526020600020905b81548152906001019060200180831161067657829003601f168201915b5050505050905086565b600160008154809291906106b090610f20565b91905055506040518060c0016040528060015481526020018681526020018581526020018481526020018381526020018281525060008060015481526020019081526020016000206000820151816000015560208201518160010155604082015181600201908051906020019061072892919061080c565b50606082015181600301908051906020019061074592919061080c565b50608082015181600401908051906020019061076292919061080c565b5060a082015181600501908051906020019061077f92919061080c565b50905050816040516107919190610fa5565b6040518091039020856001547f5fea036c56a9fe203110015d4d45fde7ec91f39e84507f4ffd536c61ed0b27ea60405160405180910390a45050505050565b60015481565b6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b82805461081890610e90565b90600052602060002090601f01602090048101928261083a5760008555610881565b82601f1061085357805160ff1916838001178555610881565b82800160010185558215610881579182015b82811115610880578251825591602001919060010190610865565b5b50905061088e9190610892565b5090565b5b808211156108ab576000816000905550600101610893565b5090565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6108d6816108c3565b81146108e157600080fd5b50565b6000813590506108f3816108cd565b92915050565b60006020828403121561090f5761090e6108b9565b5b600061091d848285016108e4565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61095b816108c3565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561099b578082015181840152602081019050610980565b838111156109aa576000848401525b50505050565b6000601f19601f8301169050919050565b60006109cc82610961565b6109d6818561096c565b93506109e681856020860161097d565b6109ef816109b0565b840191505092915050565b600060c083016000830151610a126000860182610952565b506020830151610a256020860182610952565b5060408301518482036040860152610a3d82826109c1565b91505060608301518482036060860152610a5782826109c1565b91505060808301518482036080860152610a7182826109c1565b91505060a083015184820360a0860152610a8b82826109c1565b9150508091505092915050565b6000610aa483836109fa565b905092915050565b6000602082019050919050565b6000610ac482610926565b610ace8185610931565b935083602082028501610ae085610942565b8060005b85811015610b1c5784840389528151610afd8582610a98565b9450610b0883610aac565b925060208a01995050600181019050610ae4565b50829750879550505050505092915050565b60006020820190508181036000830152610b488184610ab9565b905092915050565b610b59816108c3565b82525050565b600082825260208201905092915050565b6000610b7b82610961565b610b858185610b5f565b9350610b9581856020860161097d565b610b9e816109b0565b840191505092915050565b600060c082019050610bbe6000830189610b50565b610bcb6020830188610b50565b8181036040830152610bdd8187610b70565b90508181036060830152610bf18186610b70565b90508181036080830152610c058185610b70565b905081810360a0830152610c198184610b70565b9050979650505050505050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610c68826109b0565b810181811067ffffffffffffffff82111715610c8757610c86610c30565b5b80604052505050565b6000610c9a6108af565b9050610ca68282610c5f565b919050565b600067ffffffffffffffff821115610cc657610cc5610c30565b5b610ccf826109b0565b9050602081019050919050565b82818337600083830152505050565b6000610cfe610cf984610cab565b610c90565b905082815260208101848484011115610d1a57610d19610c2b565b5b610d25848285610cdc565b509392505050565b600082601f830112610d4257610d41610c26565b5b8135610d52848260208601610ceb565b91505092915050565b600080600080600060a08688031215610d7757610d766108b9565b5b6000610d85888289016108e4565b955050602086013567ffffffffffffffff811115610da657610da56108be565b5b610db288828901610d2d565b945050604086013567ffffffffffffffff811115610dd357610dd26108be565b5b610ddf88828901610d2d565b935050606086013567ffffffffffffffff811115610e0057610dff6108be565b5b610e0c88828901610d2d565b925050608086013567ffffffffffffffff811115610e2d57610e2c6108be565b5b610e3988828901610d2d565b9150509295509295909350565b6000602082019050610e5b6000830184610b50565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610ea857607f821691505b60208210811415610ebc57610ebb610e61565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610f2b826108c3565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f5e57610f5d610ef1565b5b600182019050919050565b600081905092915050565b6000610f7f82610961565b610f898185610f69565b9350610f9981856020860161097d565b80840191505092915050565b6000610fb18284610f74565b91508190509291505056fea2646970667358221220a49324f87505c8cd3d95cb766142e951215d5e7bafd09d14d6","e21ad0d1ef468c64736f6c634300080b0033"};

    public static final String BINARY = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", BINARY_ARRAY);

    public static final String[] SM_BINARY_ARRAY = {};

    public static final String SM_BINARY = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);

    public static final String[] ABI_ARRAY = {"[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"}],\"name\":\"RecordAdded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"imgUrl\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recordTime\",\"type\":\"string\"}],\"name\":\"addRecord\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"}],\"name\":\"getRecordsByProjectId\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"imgUrl\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recordTime\",\"type\":\"string\"}],\"internalType\":\"struct DisburseRecord.Record[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlockId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"records\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"projectId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"imgUrl\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"amount\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"recordTime\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"};

    public static final String ABI = org.fisco.bcos.sdk.v3.utils.StringUtils.joinAll("", ABI_ARRAY);

    public static final String FUNC_ADDRECORD = "addRecord";

    public static final String FUNC_GETRECORDSBYPROJECTID = "getRecordsByProjectId";

    public static final String FUNC_LASTBLOCKID = "lastBlockId";

    public static final String FUNC_RECORDS = "records";

    public static final Event RECORDADDED_EVENT = new Event("RecordAdded", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>(true) {}, new TypeReference<Uint256>(true) {}, new TypeReference<Utf8String>(true) {}));
    ;

    protected DisburseRecord(String contractAddress, Client client, CryptoKeyPair credential) {
        super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
    }

    public static String getBinary(CryptoSuite cryptoSuite) {
        return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
    }

    public static String getABI() {
        return ABI;
    }

    public List<RecordAddedEventResponse> getRecordAddedEvents(
            TransactionReceipt transactionReceipt) {
        List<Contract.EventValuesWithLog> valueList = extractEventParametersWithLog(RECORDADDED_EVENT, transactionReceipt);
        ArrayList<RecordAddedEventResponse> responses = new ArrayList<RecordAddedEventResponse>(valueList.size());
        for (Contract.EventValuesWithLog eventValues : valueList) {
            RecordAddedEventResponse typedResponse = new RecordAddedEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse.blockId = (BigInteger) eventValues.getIndexedValues().get(0).getValue();
            typedResponse.projectId = (BigInteger) eventValues.getIndexedValues().get(1).getValue();
            typedResponse.amount = (byte[]) eventValues.getIndexedValues().get(2).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public TransactionReceipt addRecord(BigInteger projectId, String imgUrl, String description,
            String amount, String recordTime) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(imgUrl), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(description), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(amount), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime)), 
                Collections.<TypeReference<?>>emptyList(), 0);
        return executeTransaction(function);
    }

    public String getSignedTransactionForAddRecord(BigInteger projectId, String imgUrl,
            String description, String amount, String recordTime) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(imgUrl), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(description), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(amount), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime)), 
                Collections.<TypeReference<?>>emptyList(), 0);
        return createSignedTransaction(function);
    }

    public String addRecord(BigInteger projectId, String imgUrl, String description, String amount,
            String recordTime, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(imgUrl), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(description), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(amount), 
                new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime)), 
                Collections.<TypeReference<?>>emptyList(), 0);
        return asyncExecuteTransaction(function, callback);
    }

    public Tuple5<BigInteger, String, String, String, String> getAddRecordInput(
            TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_ADDRECORD, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = this.functionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple5<BigInteger, String, String, String, String>(

                (BigInteger) results.get(0).getValue(), 
                (String) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue()
                );
    }

    public List<DisburseRecord.Record> getRecordsByProjectId(BigInteger projectId) throws
            ContractException {
        final Function function = new Function(FUNC_GETRECORDSBYPROJECTID, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<DisburseRecord.Record>>() {}));
        return executeCallWithSingleValueReturn(function, List.class);
    }

    public void getRecordsByProjectId(BigInteger projectId, CallCallback callback) throws
            ContractException {
        final Function function = new Function(FUNC_GETRECORDSBYPROJECTID, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<DisburseRecord.Record>>() {}));
        asyncExecuteCall(function, callback);
    }

    public BigInteger lastBlockId() throws ContractException {
        final Function function = new Function(FUNC_LASTBLOCKID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public void lastBlockId(CallCallback callback) throws ContractException {
        final Function function = new Function(FUNC_LASTBLOCKID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        asyncExecuteCall(function, callback);
    }

    public Tuple6<BigInteger, BigInteger, String, String, String, String> records(BigInteger param0)
            throws ContractException {
        final Function function = new Function(FUNC_RECORDS, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(param0)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = executeCallWithMultipleValueReturn(function);
        return new Tuple6<BigInteger, BigInteger, String, String, String, String>(
                (BigInteger) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue(), 
                (String) results.get(5).getValue());
    }

    public void records(BigInteger param0, CallCallback callback) throws ContractException {
        final Function function = new Function(FUNC_RECORDS, 
                Arrays.<Type>asList(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(param0)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        asyncExecuteCall(function, callback);
    }

    public static DisburseRecord load(String contractAddress, Client client,
            CryptoKeyPair credential) {
        return new DisburseRecord(contractAddress, client, credential);
    }

    public static DisburseRecord deploy(Client client, CryptoKeyPair credential) throws
            ContractException {
        return deploy(DisburseRecord.class, client, credential, getBinary(client.getCryptoSuite()), getABI(), null, null);
    }

    public static class Record extends DynamicStruct {
        public BigInteger blockId;

        public BigInteger projectId;

        public String imgUrl;

        public String description;

        public String amount;

        public String recordTime;

        public Record(Uint256 blockId, Uint256 projectId, Utf8String imgUrl, Utf8String description,
                Utf8String amount, Utf8String recordTime) {
            super(blockId,projectId,imgUrl,description,amount,recordTime);
            this.blockId = blockId.getValue();
            this.projectId = projectId.getValue();
            this.imgUrl = imgUrl.getValue();
            this.description = description.getValue();
            this.amount = amount.getValue();
            this.recordTime = recordTime.getValue();
        }

        public Record(BigInteger blockId, BigInteger projectId, String imgUrl, String description,
                String amount, String recordTime) {
            super(new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(blockId),new org.fisco.bcos.sdk.v3.codec.datatypes.generated.Uint256(projectId),new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(imgUrl),new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(description),new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(amount),new org.fisco.bcos.sdk.v3.codec.datatypes.Utf8String(recordTime));
            this.blockId = blockId;
            this.projectId = projectId;
            this.imgUrl = imgUrl;
            this.description = description;
            this.amount = amount;
            this.recordTime = recordTime;
        }
    }

    public static class RecordAddedEventResponse {
        public TransactionReceipt.Logs log;

        public BigInteger blockId;

        public BigInteger projectId;

        public byte[] amount;
    }
}
